home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / PixelMotionBlur / PixelMotionBlurNoMRT.fx < prev    next >
Encoding:
Text File  |  2004-09-27  |  10.2 KB  |  274 lines

  1. //-----------------------------------------------------------------------------
  2. // File: PixelMotionBlur.fx
  3. //
  4. // Desc: Effect file for image based motion blur. The HLSL shaders are used to
  5. //       calculate the velocity of each pixel based on the last frame's matrix 
  6. //       transforms.  This per-pixel velocity is then used in a blur filter to 
  7. //       create the motion blur effect.
  8. // 
  9. // Copyright (c) Microsoft Corporation. All rights reserved.
  10. //-----------------------------------------------------------------------------
  11.  
  12.  
  13. //-----------------------------------------------------------------------------
  14. // Global variables
  15. //-----------------------------------------------------------------------------
  16. float4 MaterialAmbientColor;
  17. float4 MaterialDiffuseColor;
  18.  
  19. float3 LightDir = normalize(float3(1.0f, 1.0f, 1.0f));
  20. float4 LightAmbient = { 1.0f, 1.0f, 1.0f, 1.0f };    // ambient
  21. float4 LightDiffuse = { 1.0f, 1.0f, 1.0f, 1.0f };    // diffuse
  22.  
  23. texture RenderTargetTexture;
  24. texture MeshTexture;
  25. texture CurFrameVelocityTexture;
  26. texture LastFrameVelocityTexture;
  27.  
  28. float4x4 mWorld;
  29. float4x4 mWorldViewProjection;
  30. float4x4 mWorldViewProjectionLast;
  31.  
  32. float PixelBlurConst = 1.0f;
  33. static const float NumberOfPostProcessSamples = 12.0f;
  34. float ConvertToNonHomogeneous;
  35. float VelocityCapSq = 1.0f;
  36. float RenderTargetWidth;
  37. float RenderTargetHeight;
  38.  
  39.  
  40. //-----------------------------------------------------------------------------
  41. // Texture samplers
  42. //-----------------------------------------------------------------------------
  43. sampler RenderTargetSampler = 
  44. sampler_state
  45. {
  46.     Texture = <RenderTargetTexture>;
  47.     MinFilter = POINT;  
  48.     MagFilter = POINT;
  49.  
  50.     AddressU = Clamp;
  51.     AddressV = Clamp;
  52. };
  53.  
  54. sampler CurFramePixelVelSampler = 
  55. sampler_state
  56. {
  57.     Texture = <CurFrameVelocityTexture>;
  58.     MinFilter = POINT;
  59.     MagFilter = POINT;
  60.  
  61.     AddressU = Clamp;
  62.     AddressV = Clamp;
  63. };
  64.  
  65. sampler LastFramePixelVelSampler = 
  66. sampler_state
  67. {
  68.     Texture = <LastFrameVelocityTexture>;
  69.     MinFilter = POINT;
  70.     MagFilter = POINT;
  71.  
  72.     AddressU = Clamp;
  73.     AddressV = Clamp;
  74. };
  75.  
  76. sampler MeshTextureSampler = 
  77. sampler_state
  78. {
  79.     Texture = <MeshTexture>;
  80.     MipFilter = LINEAR;
  81.     MinFilter = LINEAR;
  82.     MagFilter = LINEAR;
  83. };
  84.  
  85.  
  86. //-----------------------------------------------------------------------------
  87. // Vertex shader output structure
  88. //-----------------------------------------------------------------------------
  89. struct VS_OUTPUT
  90. {
  91.     float4 Position : POSITION;   // position of the vertex
  92.     float4 Diffuse  : COLOR0;     // diffuse color of the vertex
  93.     float2 TextureUV : TEXCOORD0;  // typical texture coords stored here
  94.     float2 VelocityUV : TEXCOORD1;  // per-vertex velocity stored here
  95. };
  96.  
  97.  
  98. //-----------------------------------------------------------------------------
  99. // Name: WorldVertexShader     
  100. // Type: Vertex shader                                      
  101. // Desc: In addition to standard transform and lighting, it calculates the velocity 
  102. //       of the vertex and outputs this as a texture coord.
  103. //-----------------------------------------------------------------------------
  104. VS_OUTPUT WorldVertexShader( float4 vPos : POSITION, 
  105.                              float3 vNormal : NORMAL,
  106.                              float2 vTexCoord0 : TEXCOORD0 )
  107. {
  108.     VS_OUTPUT Output;
  109.     float3 vNormalWorldSpace;
  110.     float4 vPosProjSpaceCurrent; 
  111.     float4 vPosProjSpaceLast; 
  112.   
  113.     vNormalWorldSpace = normalize(mul(vNormal, (float3x3)mWorld)); // normal (world space)
  114.     
  115.     // Transform from object space to homogeneous projection space
  116.     vPosProjSpaceCurrent = mul(vPos, mWorldViewProjection);
  117.     vPosProjSpaceLast = mul(vPos, mWorldViewProjectionLast);
  118.     
  119.     // Output the vetrex position in projection space
  120.     Output.Position = vPosProjSpaceCurrent;
  121.  
  122.     // Convert to non-homogeneous points [-1,1] by dividing by w 
  123.     vPosProjSpaceCurrent /= vPosProjSpaceCurrent.w;
  124.     vPosProjSpaceLast /= vPosProjSpaceLast.w;
  125.     
  126.     // Vertex's velocity (in non-homogeneous projection space) is the position this frame minus 
  127.     // its position last frame.  This information is stored in a texture coord.  The pixel shader 
  128.     // will read the texture coordinate with a sampler and use it to output each pixel's velocity.
  129.     float2 velocity = vPosProjSpaceCurrent - vPosProjSpaceLast;    
  130.     
  131.     // The velocity is now between (-2,2) so divide by 2 to get it to (-1,1)
  132.     velocity /= 2.0f;   
  133.  
  134.     // Store the velocity in a texture coord
  135.     Output.VelocityUV = velocity;
  136.         
  137.     // Compute simple lighting equation
  138.     Output.Diffuse.rgb = MaterialDiffuseColor * LightDiffuse * max(0,dot(vNormalWorldSpace, LightDir)) + 
  139.                          MaterialAmbientColor * LightAmbient;   
  140.     Output.Diffuse.a = 1.0f; 
  141.     
  142.     // Just copy the texture coordinate through
  143.     Output.TextureUV = vTexCoord0; 
  144.     
  145.     return Output;    
  146. }
  147.  
  148. //-----------------------------------------------------------------------------
  149. // Pixel shader output structure for no MRT
  150. //-----------------------------------------------------------------------------
  151. struct PS_OUTPUT_NO_MRT
  152. {
  153.     // The pixel shader can output 2+ values simulatanously if 
  154.     // d3dcaps.NumSimultaneousRTs > 1
  155.     
  156.     float4 RGBColor      : COLOR0;  // Pixel color    
  157. };
  158.  
  159. //-----------------------------------------------------------------------------
  160. // Name: WorldPixelShaderPhase1 & WorldPixelShaderPhase2
  161. // Desc: Uses multiple render passes to output 2 values one in each
  162. //       pixel shader.  The two values are color and velocity.
  163. //-----------------------------------------------------------------------------
  164. PS_OUTPUT_NO_MRT WorldPixelShaderPass1(VS_OUTPUT In)
  165. {
  166.     PS_OUTPUT_NO_MRT Output;
  167.     // Lookup mesh texture and modulate it with diffuse
  168.     Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * In.Diffuse;
  169.     return Output;
  170. }
  171.  
  172. PS_OUTPUT_NO_MRT WorldPixelShaderPass2(VS_OUTPUT In)
  173. {
  174.     PS_OUTPUT_NO_MRT Output;
  175.     Output.RGBColor = float4(In.VelocityUV,1.0f,1.0f);
  176.     return Output;
  177. }
  178.  
  179. //-----------------------------------------------------------------------------
  180. // Name: PostProcessMotionBlurPS 
  181. // Type: Pixel shader                                      
  182. // Desc: Uses the pixel's velocity to sum up and average pixel in that direction
  183. //       to create a blur effect based on the velocity in a fullscreen
  184. //       post process pass.
  185. //-----------------------------------------------------------------------------
  186. float4 PostProcessMotionBlurPS( float2 OriginalUV : TEXCOORD0 ) : COLOR
  187. {
  188.     float2 pixelVelocity;
  189.     
  190.     // Get this pixel's current velocity and this pixel's last frame velocity
  191.     // The velocity is stored in .r & .g channels
  192.     float4 curFramePixelVelocity = tex2D(CurFramePixelVelSampler, OriginalUV);
  193.     float4 lastFramePixelVelocity = tex2D(LastFramePixelVelSampler, OriginalUV);
  194.  
  195.     // If this pixel's current velocity is zero, then use its last frame velocity
  196.     // otherwise use its current velocity.  We don't want to add them because then 
  197.     // you would get double the current velocity in the center.  
  198.     // If you just use the current velocity, then it won't blur where the object 
  199.     // was last frame because the current velocity at that point would be 0.  Instead 
  200.     // you could do a filter to find if any neighbors are non-zero, but that requires a lot 
  201.     // of texture lookups which are limited and also may not work if the object moved too 
  202.     // far, but could be done multi-pass.
  203.     float curVelocitySqMag = curFramePixelVelocity.r * curFramePixelVelocity.r +
  204.                              curFramePixelVelocity.g * curFramePixelVelocity.g;
  205.     float lastVelocitySqMag = lastFramePixelVelocity.r * lastFramePixelVelocity.r +
  206.                               lastFramePixelVelocity.g * lastFramePixelVelocity.g;
  207.                                    
  208.     if( lastVelocitySqMag > curVelocitySqMag )
  209.     {
  210.         pixelVelocity.x =  lastFramePixelVelocity.r * PixelBlurConst;   
  211.         pixelVelocity.y = -lastFramePixelVelocity.g * PixelBlurConst;
  212.     }
  213.     else
  214.     {
  215.         pixelVelocity.x =  curFramePixelVelocity.r * PixelBlurConst;   
  216.         pixelVelocity.y = -curFramePixelVelocity.g * PixelBlurConst;    
  217.     }
  218.     
  219.     // For each sample, sum up each sample's color in "Blurred" and then divide
  220.     // to average the color after all the samples are added.
  221.     float3 Blurred = 0;    
  222.     for(float i = 0; i < NumberOfPostProcessSamples; i++)
  223.     {   
  224.         // Sample texture in a new spot based on pixelVelocity vector 
  225.         // and average it with the other samples        
  226.         float2 lookup = pixelVelocity * i / NumberOfPostProcessSamples + OriginalUV;
  227.         
  228.         // Lookup the color at this new spot
  229.         float4 Current = tex2D(RenderTargetSampler, lookup);
  230.         
  231.         // Add it with the other samples
  232.         Blurred += Current.rgb;
  233.     }
  234.     
  235.     // Return the average color of all the samples
  236.     return float4(Blurred / NumberOfPostProcessSamples, 1.0f);
  237. }
  238.  
  239.  
  240. //-----------------------------------------------------------------------------
  241. // Name: WorldWithVelocity
  242. // Type: Technique                                     
  243. // Desc: Renders the scene's color in pass 0 and writes 
  244. //       pixel velocity in pass 1.
  245. //-----------------------------------------------------------------------------
  246. technique WorldWithVelocity
  247. {
  248.     pass P0
  249.     {          
  250.         VertexShader = compile vs_2_0 WorldVertexShader();
  251.         PixelShader  = compile ps_2_0 WorldPixelShaderPass1();
  252.     }
  253.     pass P1
  254.     {          
  255.         VertexShader = compile vs_2_0 WorldVertexShader();
  256.         PixelShader  = compile ps_2_0 WorldPixelShaderPass2();
  257.     }
  258. }
  259. //-----------------------------------------------------------------------------
  260. // Name: PostProcessMotionBlur
  261. // Type: Technique                                     
  262. // Desc: Renders a full screen quad and uses velocity information stored in 
  263. //       the textures to blur image.
  264. //-----------------------------------------------------------------------------
  265. technique PostProcessMotionBlur
  266. {
  267.     pass P0
  268.     {        
  269.         PixelShader = compile ps_2_0 PostProcessMotionBlurPS();
  270.     }
  271. }
  272.  
  273.  
  274.